package com.kelvem.saas.workbanch.fsm.resolver;

import com.kelvem.saas.workbanch.core.utils.StringUtil;
import com.kelvem.saas.workbanch.fsm.container.EntityMapppingContainer;
import com.kelvem.saas.workbanch.fsm.core.EntityMappingEnum;
import com.kelvem.saas.workbanch.fsm.core.FsmException;
import com.kelvem.saas.workbanch.fsm.entity.Entity;
import com.kelvem.saas.workbanch.fsm.entity.EntityMapppingNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.MultiValueMap;

import java.lang.reflect.Field;

@Slf4j
public class One2OneResolver {

    public static void resolve(ScannedGenericBeanDefinition candidate) {
        /**
         * One2One
         */
        String mapperKey = "com.kelvem.saas.workbanch.fsm.anno.entity.One2One";
        AnnotationMetadata meta = candidate.getMetadata();
        MultiValueMap<String, Object> map = meta.getAllAnnotationAttributes(mapperKey);
        if (map == null || map.size() <= 0) {
            return;
        }
        log.info(map + "");
        Class<? extends Entity> rightClazz = (Class<? extends Entity>)map.getFirst("entityClazz");
        String leftEntity = candidate.getMetadata().getClassName();
        Class<? extends Entity> leftClazz;
        try {
            leftClazz = (Class<? extends Entity>)Class.forName(leftEntity);
        } catch (Exception e) {
            String msg = "@One2One, entity=" + leftEntity + ", " + e.getMessage();
            log.error(msg);
            throw new FsmException(msg, e);
        }
        String leftKey = map.getFirst("key").toString();
        String rightKey = "id";
        if (StringUtil.isEmpty(leftKey)) {
            String clazzName = rightClazz.getSimpleName();
            leftKey = clazzName.substring(0,1).toLowerCase() + clazzName.substring(1, clazzName.length() - 6) + "Id";
        }
        try {
            Field leftField = null;
            try {
                leftField = leftClazz.getField(leftKey);
            } catch (Exception ex) {
                leftField = leftClazz.getDeclaredField(leftKey);
            }
            if(!leftField.getType().equals(Long.class)) {
                String msg = String.format("Clazz[%s]的@One2One(key=\"%s\"), 在%s.%s类型必须为Long, 请检查注解",
                        leftClazz.getSimpleName(), leftKey, leftClazz.getSimpleName(), leftKey);
                log.error(msg);
                throw new FsmException(msg);
            }
        } catch (NoSuchFieldException e) {
            String msg = String.format("Clazz[%s]的@One2One(key=\"%s\"), 在%s未发现Field, 请检查注解",
                    leftClazz.getSimpleName(), leftKey, leftClazz.getSimpleName());
            log.error(msg);
            throw new FsmException(msg, e);
        }

        EntityMapppingNode mapping = new EntityMapppingNode(EntityMappingEnum.one2one, leftClazz, leftKey, rightClazz, rightKey);
        EntityMapppingContainer.addMapping(mapping);

        // todo
//        log.info(mapping.toString());
    }
}
